/********************************************************************************
* @file    ls_gpio.h
* @author  jianqiang.xue
* @version V1.1.0
* @date    2022-12-11
* @brief   业务类--GPIO定义
********************************************************************************/
#ifndef __LS_GPIO_H
#define __LS_GPIO_H
#define LS_IO_VERSION "CX32L003_通用模板"

#include "cx32l003_hal.h"
#include "cx32l003_hal_def.h"
#include "ls_syscfg.h"
#include "bsp_gpio.h"
#include "bsp_exti.h"

/* GPIO_EXTI_INT_EDGE;             // 中断类型 边沿触发
    GPIO_EXTI_INT_LOWFALL;  // 下降沿触发中断
    GPIO_EXTI_INT_HIGHRISE; // 上升沿触发中断
    GPIO_EXTI_INT_FALLRISE; // 下降沿上升沿都触发中断
GPIO_EXTI_INT_LEVEL;            // 中断类型 电平触发
    GPIO_EXTI_INT_LOWFALL;  // 低电平触发中断
    GPIO_EXTI_INT_HIGHRISE; // 高电平触发中断 */

#define GPIO_CLK(GPIO)                              (RCC_HCLKEN_##GPIO##CKEN)
#define GPIO_APBx                                   (0)
/************************************GPIO***********************************/
#define LS_IO_NUM                                   (16)
/* Public Struct -------------------------------------------------------------*/

union io_support_t {
    uint64_t val; // 对外值
    struct {
        uint64_t swo                : 1;

        uint64_t adc0_ch0           : 1;
        uint64_t adc0_ch1           : 1;
        uint64_t adc0_ch2           : 1;
        uint64_t adc0_ch3           : 1;
        uint64_t adc0_ch4           : 1;
        uint64_t adc0_ch5           : 1;
        uint64_t adc0_ch6           : 1;
        uint64_t adc1_ch0           : 1;
        uint64_t adc1_ch1           : 1;
        uint64_t adc1_ch2           : 1;
        uint64_t adc1_ch3           : 1;
        uint64_t adc1_ch4           : 1;
        uint64_t adc1_ch5           : 1;
        uint64_t adc1_ch6           : 1;

        uint64_t tim1_ch1           : 1; // PWM0
        uint64_t tim1_ch2           : 1; // PWM1
        uint64_t tim1_ch3           : 1; // PWM2
        uint64_t tim1_ch4           : 1; // PWM3
        uint64_t tim2_ch1           : 1; // PWM4
        uint64_t tim2_ch2           : 1; // PWM5
        uint64_t tim2_ch3           : 1; // PWM6
        uint64_t tim2_ch4           : 1; // PWM7

        uint64_t uart0_tx           : 1;
        uint64_t uart0_rx           : 1;
        uint64_t uart1_tx           : 1;
        uint64_t uart1_rx           : 1;
        uint64_t uart2_tx           : 1;
        uint64_t uart2_rx           : 1;

        uint64_t i2c0_scl           : 1; // 硬件IIC
        uint64_t i2c0_sda           : 1;
        uint64_t i2c1_scl           : 1;
        uint64_t i2c1_sda           : 1;
        uint64_t i2c_scl_soft       : 1; // 软件IIC
        uint64_t i2c_sda_soft       : 1;

        uint64_t spi0_clk           : 1;
        uint64_t spi0_mosi          : 1;
        uint64_t spi0_miso          : 1;
        uint64_t spi0_nss           : 1;

        uint64_t spi1_clk           : 1;
        uint64_t spi1_mosi          : 1;
        uint64_t spi1_miso          : 1;
        uint64_t spi1_nss           : 1;

#if !LS_IO_EXTEND_SUPPORT
        uint64_t reserve            : 7;
#endif
    } bit;
};

typedef enum {
    IO_TYPE_IN_NULL = 0, // 默认输入 无上下拉
    IO_TYPE_IN_PULLUP,   // 输入，上拉
    IO_TYPE_IN_PULLDOWN, // 输入，下拉

    IO_TYPE_OUT_PP,      // 默认输出 推免输出
    IO_TYPE_OUT_OD,      // 开漏输出
    // 中断输入
    IO_TYPE_INIRQ_LEVEL_LOW,     // 电平触发-低电平
    IO_TYPE_INIRQ_LEVEL_HIGH,    // 电平触发-高电平
    IO_TYPE_INIRQ_EDGE_LOWFALL,  // 边沿触发-下降沿
    IO_TYPE_INIRQ_EDGE_HIGHRISE, // 边沿触发-上降沿
    IO_TYPE_INIRQ_EDGE_FALLRISE, // 边沿触发-任意电平变化

    IO_TYPE_SWO,        // 默认烧录脚
    IO_TYPE_KEY,        // 按键，会注册到软定时器中扫描
    IO_TYPE_MATRIX_KEY_X, // 矩阵键盘X轴，会注册到软定时器中扫描
    IO_TYPE_MATRIX_KEY_Y, // 矩阵键盘Y轴，会注册到软定时器中扫描
    IO_TYPE_W2812X,

    IO_TYPE_ADC0_CH0,
    IO_TYPE_ADC0_CH1,
    IO_TYPE_ADC0_CH2,
    IO_TYPE_ADC0_CH3,
    IO_TYPE_ADC0_CH4,
    IO_TYPE_ADC0_CH5,
    IO_TYPE_ADC0_CH6,
    IO_TYPE_ADC1_CH0,
    IO_TYPE_ADC1_CH1,
    IO_TYPE_ADC1_CH2,
    IO_TYPE_ADC1_CH3,
    IO_TYPE_ADC1_CH4,
    IO_TYPE_ADC1_CH5,
    IO_TYPE_ADC1_CH6,

    IO_TYPE_TIM1_CH1, // PWM0
    IO_TYPE_TIM1_CH2, // PWM1
    IO_TYPE_TIM1_CH3, // PWM2
    IO_TYPE_TIM1_CH4, // PWM3
    IO_TYPE_TIM2_CH1, // PWM4
    IO_TYPE_TIM2_CH2, // PWM5
    IO_TYPE_TIM2_CH3, // PWM6
    IO_TYPE_TIM2_CH4, // PWM7

    IO_TYPE_UART0_TX,   // 串口，通过命令配置电气特性
    IO_TYPE_UART0_RX,
    IO_TYPE_UART1_TX,   // 串口，通过命令配置电气特性
    IO_TYPE_UART1_RX,
    IO_TYPE_UART2_TX,
    IO_TYPE_UART2_RX,

    IO_TYPE_I2C0_SCL,   // 硬件IIC
    IO_TYPE_I2C0_SDA,   // 硬件IIC
    IO_TYPE_I2C1_SCL,
    IO_TYPE_I2C1_SDA,
    IO_TYPE_I2C_SCL_SOFT,   // 软件IIC
    IO_TYPE_I2C_SDA_SOFT,   // 软件IIC

    IO_TYPE_SPI0_CLK,
    IO_TYPE_SPI0_MOSI,
    IO_TYPE_SPI0_MISO,
    IO_TYPE_SPI0_NSS,
    IO_TYPE_SPI1_CLK,
    IO_TYPE_SPI1_MOSI,
    IO_TYPE_SPI1_MISO,
    IO_TYPE_SPI1_NSS,

    IO_TYPE_MAX,
} io_type_t;

extern const union io_support_t g_io_support[LS_IO_NUM];
extern const io_type_t g_io_default_type[LS_IO_NUM];
extern const bsp_gpio_t g_io_cfg[LS_IO_NUM];
#ifdef LS_IO
const bsp_gpio_t g_io_cfg[LS_IO_NUM] = {
    {(GPIOD), (GPIO_PIN_2), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_3), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_4), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_5), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOD), (GPIO_PIN_6), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOC), (GPIO_PIN_3), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_4), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_5), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOC), (GPIO_PIN_6), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOB), (GPIO_PIN_4), GPIO_CLK(GPIOB), (0), (GPIOB_IRQn)},
    {(GPIOB), (GPIO_PIN_5), GPIO_CLK(GPIOB), (0), (GPIOB_IRQn)},
    {(GPIOA), (GPIO_PIN_3), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
    {(GPIOD), (GPIO_PIN_1), GPIO_CLK(GPIOD), (0), (GPIOD_IRQn)},
    {(GPIOC), (GPIO_PIN_7), GPIO_CLK(GPIOC), (0), (GPIOC_IRQn)},
    {(GPIOA), (GPIO_PIN_1), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
    {(GPIOA), (GPIO_PIN_2), GPIO_CLK(GPIOA), (0), (GPIOA_IRQn)},
};

const union io_support_t g_io_support[LS_IO_NUM] = {
    {0x808010010}, {0x1100020}, {0x888000}, {0x2022C00040}, {0x1045110080},
    {0x42220004}, {0x24440008}, {0x808000000}, {0x1010408002}, {0x4020800000},
    {0x841080000}, {0x4010200000}, {0x2000001}, {0x4100001}, {0x45000000},
    {0x4022920000}, 
};

const io_type_t g_io_default_type[LS_IO_NUM] = {
    IO_TYPE_TIM1_CH2, IO_TYPE_TIM2_CH2, IO_TYPE_TIM1_CH1, IO_TYPE_TIM2_CH4, IO_TYPE_ADC0_CH6,
    IO_TYPE_TIM1_CH3, IO_TYPE_TIM1_CH4, IO_TYPE_TIM2_CH1, IO_TYPE_ADC0_CH0, IO_TYPE_IN_NULL,
    IO_TYPE_IN_NULL, IO_TYPE_TIM2_CH3, IO_TYPE_SWO, IO_TYPE_SWO, IO_TYPE_UART0_RX,
    IO_TYPE_UART0_TX,
};
#else
#endif

#endif
